using System;
using System.Collections.Generic;
using System.Text;
using MatrixDataStructures;
using System.Drawing;
using ResampleTest;
using System.Windows.Forms;

namespace MatrixResizer
{
    public class MatrixResize
    {
        int c;
        public MatrixResize()
        {
            c = int.Parse(CustomInputBox2.Show(
                "0. Box Filter (Nearest Neighbor)              \n" + "1. Triangle Filter (Low/Tent)\n" +
                "2. Hermite Filter (Cubic Spline of Hermite)   \n" + "3. Bell Filter (Average Quality)\n" +
                "4. Cubic B-Spline Filter (Most Blurry)          \n" + "5. Lanczos 3 Filter (Windowed Sinc)\n" +
                "6. Mitchell Filter (Excellent for Upsampling) \n" + "7. Cosine Filter\n" +
                "8. Catmull Rom Filter (Used in Warping)        \n" + "9. Quadratic Filter (Performance Optimized)\n" +
                "10. Quadratic B-Spline Filter (Quadratic Bezier)\n" + "11. Cubic Convolution Filter (Edge Enhancing)\n" +
                "12. Lanczos 8 Filter (Larger Sinc)             ", " Resize Filter Options", "0", new Size(410, 270)).Text);
        } //constructors 
        public MatrixResize(int choice)
        {
            if (choice < 0)
                c = 12;
            if (choice > 12)
                c = 12;

            this.c = choice;
        } //constructors 

        public Matrix3DInt16 Resize(Matrix3DInt16 Data, double xnew, double ynew, double znew)
        {
            Int16 max = Data.Maximum();
            Int16 min = Data.Minimum();
            int value = 0;

            int x = Convert.ToInt16(Math.Round((double)Data.x));
            int y = Convert.ToInt16(Math.Round((double)Data.y));
            int z = Convert.ToInt16(Math.Round((double)Data.z));

            int xn = Convert.ToInt16(Math.Round(xnew));
            int yn = Convert.ToInt16(Math.Round(ynew));
            int zn = Convert.ToInt16(Math.Round(znew));

            Matrix3DInt16 temp = new Matrix3DInt16(x, yn, zn);
            for (int i = 0; i < Data.x; i++)
            {
                Bitmap Slice = new Bitmap(y, z);
                for (int j = 0; j < y; j++)
                    for (int k = 0; k < z; k++)
                    {
                        value = (Data[i, j, k] - min) * 255 / (max - min);
                        Slice.SetPixel(j, k, Color.FromArgb(value, value, value));
                    }

                ResamplingService resampling = new ResamplingService(Slice, c);
                resampling.Resample(yn, zn);
                Slice = resampling.Output;

                for (int j = 0; j < yn; j++)
                    for (int k = 0; k < zn; k++)
                        temp[i, j, k] = (Int16)((((int)Slice.GetPixel(j, k).R) * (max - min) / 255) + min);
            }
            Matrix3DInt16 temp2 = new Matrix3DInt16(xn, temp.y, temp.z);
            for (int j = 0; j < temp.y; j++)
            {
                Bitmap Slice = new Bitmap(temp.x, temp.z);
                for (int i = 0; i < temp.x; i++)
                    for (int k = 0; k < temp.z; k++)
                    {
                        value = (temp[i, j, k] - min) * 255 / (max - min);
                        Slice.SetPixel(i, k, Color.FromArgb(value, value, value));
                    }

                ResamplingService resampling = new ResamplingService(Slice, c);
                resampling.Resample(xn, zn);
                Slice = resampling.Output;

                for (int i = 0; i < xn; i++)
                    for (int k = 0; k < zn; k++)
                        temp2[i, j, k] = (Int16)((((int)Slice.GetPixel(i, k).R) * (max - min) / 255) + min);
            }
            temp.Dispose();
            return temp2;
        }
        public Matrix3DSingle Resize(Matrix3DSingle Data, double xnew, double ynew, double znew)
        {
            Single max = Data.Maximum();
            Single min = Data.Minimum();
            int value = 0;

            int x = Convert.ToInt16(Math.Round((double)Data.x));
            int y = Convert.ToInt16(Math.Round((double)Data.y));
            int z = Convert.ToInt16(Math.Round((double)Data.z));

            int xn = Convert.ToInt16(Math.Round(xnew));
            int yn = Convert.ToInt16(Math.Round(ynew));
            int zn = Convert.ToInt16(Math.Round(znew));

            Matrix3DSingle temp = new Matrix3DSingle(x, yn, zn);
            for (int i = 0; i < Data.x; i++)
            {
                Bitmap Slice = new Bitmap(y, z);
                for (int j = 0; j < y; j++)
                    for (int k = 0; k < z; k++)
                    {
                        value = (int)((Data[i, j, k] - min) * 255 / (max - min));
                        Slice.SetPixel(j, k, Color.FromArgb(value, value, value));
                    }

                ResamplingService resampling = new ResamplingService(Slice, c);
                resampling.Resample(yn, zn);
                Slice = resampling.Output;

                for (int j = 0; j < yn; j++)
                    for (int k = 0; k < zn; k++)
                        temp[i, j, k] = (Single)((((int)Slice.GetPixel(j, k).R) * (max - min) / 255) + min);
            }

            Matrix3DSingle temp2 = new Matrix3DSingle(xn, temp.y, temp.z);
            for (int j = 0; j < temp.y; j++)
            {
                Bitmap Slice = new Bitmap(temp.x, temp.z);
                for (int i = 0; i < temp.x; i++)
                    for (int k = 0; k < temp.z; k++)
                    {
                        value = (int)((temp[i, j, k] - min) * 255 / (max - min));
                        Slice.SetPixel(i, k, Color.FromArgb(value, value, value));
                    }

                ResamplingService resampling = new ResamplingService(Slice, c);
                resampling.Resample(xn, zn);
                Slice = resampling.Output;

                for (int i = 0; i < xnew; i++)
                    for (int k = 0; k < znew; k++)
                        temp2[i, j, k] = (Single)((((int)Slice.GetPixel(i, k).R) * (max - min) / 255) + min);
            }
            temp.Dispose();
            return temp2;
        }

    }
}